#pragma once

#include<functional>
#include<cassert>
#include<pthread.h>


namespace Thread{
    class thread{
        private:
            static void* start_routine(void* args){
                thread* td = static_cast<thread*>(args);
                return td->_func(td->_args);
            }
        public:
            typedef std::function<void*(void*)> func_t;
        
            thread()
            {   char buffer[1024];
                snprintf(buffer,sizeof buffer,"thread-%d",threadnum++);
                _name = buffer;
            }

            void start(func_t func,void* args = nullptr){
                _func = func;
                _args = args;
                int n = pthread_create(&_tid,nullptr,start_routine,this);
                assert(n == 0);
                (void)n;
            }
            
            std::string getname(){
                return _name;
            }

            void join(){
                int n = pthread_join(_tid,nullptr);
                assert( n == 0 );
                (void ) n;
            }
            ~thread(){
            }
        
        private:
            std::string _name;
            pthread_t _tid;
            func_t _func;
            void* _args;
            static int threadnum;
        };
        int thread::threadnum = 1;        
}
